(function() {
	var tpl = function() {
		/*<el-dialog v-model="visible" :close-on-click-modal="false" :title="title" :custom-class="customClass" size="large">
			<el-row :gutter="20">
				<el-col :span="16">
					<el-tabs @tab-click="_changeTab">
						<el-tab-pane v-for="(tab, index) in tabs" :label="tab.name" :key="tab.id">
							<div class="container_" :class="{filter_options: tab.isPersonSeleted}">
								<div class="filter_option" v-if="tab.isPersonSeleted">
									<el-form :ref="tab.id + '_form'" class="option_container" :model="tab.form" :style="{height: tab.treeHeight + 'px'}">
										<el-form-item class="option_item" v-for="option in tab.form.options" :key="option.formname">
											<el-select
												v-if="option.type==='select'"
												v-model="option.model"
												:name="option.formname"
												filterable
												:clearable="true"
												:multiple="option.multiple"
												:placeholder="'按' + option.label + '进行筛选'">
												<el-option
													v-for="item in option.options"
													:key="item.value"
													:label="item.text"
													:value="item.value">
												</el-option>
											</el-select>
											<el-input v-else :placeholder="'按' + option.label + '进行搜索'" icon="search" v-model="option.model" @keyup.enter.native="getFilterValue(index)"></el-input>
										</el-form-item>
									</el-form>
									<div class="filter_btns">
										<el-button class="reset-btn" @click="resetFilter(index)">重置</el-button>
										<el-button class="filter-btn" type="primary" @click="getFilterValue(index)">筛选</el-button>
									</div>
								</div>
								<div class="tree">
									<el-input v-if="tab.search" placeholder="输入关键字进行过滤" :value="tab.filterText"></el-input>
									<el-table @select="select" :height="tab.treeHeight+42" v-if="tab.isPersonSeleted" @selection-change="selectionChange($event, tab)" :ref="tab.id" :data="tab.data">
										<el-table-column type="selection"></el-table-column>
										<el-table-column :prop="tab.defaultProps.label" label="全选 "></el-table-column>
										<el-table-column prop="userAccount" show-overflow-tooltip label=""></el-table-column>
										<el-table-column prop="dept" show-overflow-tooltip label=""></el-table-column>
									</el-table>
									<div v-else>
										<el-tree
											:filter-node-method="filterNode"
											:ref="tab.id"
											:data="tab.data"
											highlight-current
											default-expand-all
											:show-checkbox="!tab.singleSelet"
											:node-key="tab.defaultProps.id"
											:check-strictly="true"
											:expand-on-click-node="false"
											:props="tab.defaultProps"
											@check-change="handleCheckChange"
											@current-change="_handleCurrentChange">
										</el-tree>
										<div class="checkall" v-if="!tab.singleSelet">
											<el-checkbox @change="checkAll(tab.checked, tab.id)" v-model="tab.checked">全选</el-checkbox>
										</div>
									</div>
								</div>
							</div>
						</el-tab-pane>
					</el-tabs>
				</el-col>
				<el-col :span="8">
					<div v-for="(tab, index) in tabs" :style="tab.display" class="seleted_container">
						<div class="title">
							<div class="center">
								已选{{tab.name}}{{seletedCount[index]}}
							</div>
							<div class="right" style="opacity: 0;">
								保存为我的分类
							</div>
						</div>
						<div class="content" :style="tab.styleObj">
							<div class="seleted_persons">
								<div class="seleted_person" v-for="(checked, index_) in tab.allCheckeds">
								<i v-if="tab.icon" class="iconfont" :class="tab.icon"></i>
									<img v-else :src="checked.photoUrl || '/templates/img/default.jpg'" width="60" height="60" @error="imgError($event)">
									<p v-if="tab.isPersonSeleted" v-text="checked.userName"></p>
									<p v-else v-text="checked.name"></p>
									<p v-if="tab.isPersonSeleted" class="remove_from_seleted" @click="remove(checked.userId, index_, tab.id , true)"><span>╳</span></p>
									<p v-else class="remove_from_seleted" @click="remove(checked.id, index_, tab.id , true)"><span>╳</span></p>
								</div>
							</div>
						</div>
					</div>
				</el-col>
			</el-row>
			<span slot="footer" class="dialog-footer">
				<el-button type="primary" @click="submit">确 定</el-button>
				<el-button @click="visible = false">取 消</el-button>
			</span>
		</el-dialog>*/
	};

	function genid() {
		return Math.floor(Math.random() * (9999 - 1000 + 1) + 1000);
	}

	function fnToString(fn) {
		return /\*(.*?)\*/g.exec(fn.toString().replace(/\s+/g, " "))[1].trim();
	}

	function isFunction(o) {
		return Object.prototype.toString.call(o) === "[object Function]";
	}

	function VanyFilter_(setting) {
		var mountEl = setting.mountEl.split("#"),
			id = "VanyFilter" + genid(),
			div = document.createElement("div");
		div.setAttribute("id", id);
		div.innerHTML = fnToString(tpl);
		mountEl = mountEl.length === 1 ? document.getElementsByTagName(mountEl)[0] : document.getElementById(mountEl[1]);
		mountEl.appendChild(div);
		var vanyfilter = new Vue({
			el: "#" + id,
			data: function() {
				var watch = {};
				for(var i = 0; i < setting.tabs.length; i++) {
					// 保存树数据
					setting.tabs[i].data = [];
					// 树高度
					if(window.innerHeight <= 768){
						setting.tabs[i].treeHeight = 304;
					}else{
						setting.tabs[i].treeHeight = 504;
					}
					
					// TODO用于搜索
					setting.tabs[i].filterText = "";
					// 对于人员筛选器的过滤选项集合
					setting.tabs[i].form = {
						options: []
					};
					// 分页
					if(setting.tabs[i].pagination) {
						if(setting.tabs[i].params === undefined) {
							setting.tabs[i].params = {};
						}
						setting.tabs[i].params.pageSize = 100;
						setting.tabs[i].params.pageIndex = 1;
						setting.tabs[i].nodataFlag = false;
						setting.tabs[i].total = 0;
						setting.tabs[i].pages = 0;
						setting.tabs[i].pageNum = 0;
					}
					// 树的所有已勾选节点ID
					setting.tabs[i].allNodesId = [];
					// 树的所有已勾选节点
					setting.tabs[i].allCheckeds = [];
					// 全选状态
					setting.tabs[i].checked = false;
					// 单选
					setting.tabs[i].singleSelet = setting.tabs[i].singleSelet;
					setting.tabs[i].icon = setting.tabs[i].icon;
					setting.tabs[i].defaultProps = setting.tabs[i].defaultProps || {
						children: 'children',
						label: 'name',
						id: "id"
					};
					setting.tabs[i].display = {
						display: "none"
					};
					setting.tabs[i].styleObj = {
						"height": "",
						"overflow-y": "auto"
					};
					if(i === 0) {
						setting.tabs[i].display = {
							display: "block"
						}
					}
				}
				return {
					visible: true,
					title: setting.title,
					tabs: setting.tabs,
					isIE: !!window.VBArray
				}
			},
			mounted: function() {
				for(var i = 0; i < this.tabs.length; i++) {
					!this.tabs[i].isPersonSeleted ? this.getData(this.tabs[i]) : this.getFilter(this.tabs[i]);
				}
			},
			computed: {
				seletedCount: function() {
					return this.tabs.map(function(item) {
						return item.allNodesId.length !== 0 ? "(" + item.allNodesId.length + ")" : "";
					});
				},
				customClass: function(){
					if(this.isIE){
						return "border_dialog center_dialog vanymodal_vueversion isIE";
					}else{
						return "border_dialog center_dialog vanymodal_vueversion";
					}
				}
			},
			watch: {
				filterText: function(val) {
					console.log(val)
				}
			},
			methods: {
				imgError: function(e){
					e.srcElement.src = "/templates/img/default.jpg";
				},
				/**
				 * 设置树高度
				 * tabObj：Object tab设置对象
				 */
				setHeight: function(tabObj) {
					var ref_ = this.$refs[tabObj.id][0];
					// 22是全选高度
					var height_ = tabObj.treeHeight + 22;
					if(tabObj.singleSelet) {
						// 20是全选上下padding值
						ref_.$el.style.height = height_ + 20 + 'px';
						tabObj.styleObj.height = height_ + "px";
					} else {
						ref_.$el.style.height = tabObj.treeHeight + 'px';
						tabObj.styleObj.height = height_ + 20 + "px";
					}
				},
				/**
				 * 获取筛选项——只针对人员筛选器
				 * tabObj：Object tab设置对象
				 */
				getFilter: function(tabObj) {
					var loadingEl = "#" + this.$el.id + " .filter_option";
					VanyAjax(tabObj.filterUrl, tabObj.params, "GET", loadingEl).done(function(data) {
						for(var i = 0; i < data.length; i++) {
							if(data[i].type === "input") {
								data[i].model = "";
							} else {
								if(data[i].multiple) {
									data[i].model = [];
								} else {
									data[i].model = "";
								}
							}
							if(data[i].istree) {
								if(data[i].key) {
									data[i].options = this.cleanTreeData(data[i].options, data[i].key, []);
								} else {
									data[i].options = this.cleanTreeData(data[i].options, {
										id: "id",
										name: "name",
										children: "children"
									}, []);
								}
							} else {
								if(data[i].key) {
									data[i].options = this.cleanSelectData(data[i].options, data[i].key);
								}
							}
						};
						tabObj.form.options = data;
						this.getData(tabObj);
						this.$nextTick(function() {
							this.setHeight(tabObj);
						});
					}, false, this);
				},
				cleanTreeData: function(arr, keyObj, newArr) {
					for(var i = 0; i < arr.length; i++) {
						newArr.push({
							text: arr[i][keyObj.name],
							value: arr[i][keyObj.id]
						});
						if(arr[i][keyObj.children]) {
							this.cleanTreeData(arr[i][keyObj.children], keyObj, newArr);
						}
					}
					return newArr;
				},
				cleanSelectData: function(arr, keyObj) {
					return arr.map(function(item) {
						return {
							text: item[keyObj.name],
							value: item[keyObj.id]
						}
					});
				},
				getRowById: function(id, arr) {
					for(var i = 0; i < arr.length; i++) {
						if(id === arr[i].userId) {
							return arr[i];
						}
					}
					return false;
				},
				/**
				 * 获取tree数据
				 * tabObj：Object tab设置对象
				 */
				getData: function(tabObj) {
					if(tabObj.pagination && tabObj.nodataFlag) {
						return;
					}
					var loadingEl = "#" + this.$el.id + " .tree";
					VanyAjax(tabObj.url, tabObj.params, "GET", loadingEl).done(function(data) {
						// 分页逻辑判断
						if(tabObj.pagination) {
							if(data.total === 0) {
								tabObj.nodataFlag = true;
								return;
							}
							if(tabObj.params.pageIndex * tabObj.params.pageSize >= data.total) {
								tabObj.nodataFlag = true;
							}
							tabObj.pages = data.pages;
							tabObj.total = data.total;
							tabObj.pageNum = data.pageNum;
							tabObj.params.pageIndex++;
							var temp_ = this._setAllNodesId(data.list, tabObj.id, tabObj.defaultProps);
							for(var i = 0; i < temp_.length; i++) {
								tabObj.data.push(temp_[i]);
							}
							if(!tabObj.firstLoad) {
								// 监听scroll
								var tablebody_ = this.$refs[tabObj.id][0].$el;
								var self = this;
								tablebody_ = tablebody_.getElementsByClassName("el-table__body-wrapper")[0];
								tablebody_.onscroll = function(e) {
									self.paginationLoading(tabObj, e);
								}
								tabObj.firstLoad = true;
							}
							this.$nextTick(function() {
								this.setHeight(tabObj);
								var ref_ = this.$refs[tabObj.id][0];
								if(tabObj.writeBackIds) {
									var writeBackIds = tabObj.writeBackIds.split(",");
									for(var i = 0; i < writeBackIds.length; i++) {
										var row = this.getRowById(writeBackIds[i], tabObj.data);
										if(row) {
											ref_.toggleRowSelection(row, true);
										}
									}
								}
							});
						} else {
							tabObj.data = this._setAllNodesId(data, tabObj.id, tabObj.defaultProps);
							this.$nextTick(function() {
								this.setHeight(tabObj);
								var ref_ = this.$refs[tabObj.id][0];
								if(tabObj.writeBackIds) {
									var writeBackIds = tabObj.writeBackIds.split(",");
									ref_.setCheckedKeys(writeBackIds);
								}
							});
						}
					}, false, this);
				},
				writeBack: function(tabId, checkedIds){
					var ref_ = this.$refs[tabId][0];
					ref_.setCheckedKeys(checkedIds.split(","));
				},
				/**
				 * 勾选/取消勾选指定tab下树的所有节点
				 * checked：Boolean true表示勾选全部，false表示取消勾选全部
				 * tabName： String tab id
				 */
				checkAll: function(checked, tabName) {
					var ref_ = this.$refs[tabName][0];
					if(checked) {
						var tabindex = this.getTabSettingByName(tabName),
							allNodesId = this.getAllNodesId(this.tabs[tabindex].data, [], this.tabs[tabindex].defaultProps);
						ref_.setCheckedKeys(allNodesId);
					} else {
						ref_.setCheckedKeys([]);
					}
				},
				select: function(selection, row) {
					var inFlag = [];
					for(var i = 0; i < selection.length; i++) {
						if(row.userId === selection[i].userId) {
							inFlag.push(1);
							break
						}
					}
					if(inFlag.length === 0) {
						var index_ = this.getTabSettingByName(row.treesrc_),
							tab = this.tabs[index_],
							ref_ = this.$refs[row.treesrc_][0];
						for(var i = 0; i < tab.allNodesId.length; i++) {
							if(row.userId === tab.allNodesId[i]) {
								this.remove(row.userId, i, row.treesrc_, true);
							}
						}
					}
				},
				/*用于人员筛选器*/
				selectionChange: function(selection, tabObj) {
					if(selection.length) {
						for(var i = 0; i < selection.length; i++) {
							this.add(selection[i], tabObj);
						}
					} else {
						for(var i = 0; i < tabObj.data.length; i++) {
							for(var j = 0; j < tabObj.allNodesId.length; j++) {
								if(tabObj.data[i].userId === tabObj.allNodesId[j]) {
									this.remove(tabObj.data[i].userId, j, tabObj.id, true);
									break;
								}
							}
						}
					}
				},
				/**
				 * 节点勾选状态发生改变的回调
				 * data：节点数据
				 * checked：节点勾选状态
				 * indeterminate：可忽略该参数
				 */
				handleCheckChange: function(data, checked, indeterminate) {
					var index_ = this.getTabSettingByName(data.treesrc_),
						tab = this.tabs[index_];
					if(checked) {
						this.add(data);
					} else {
						var index_ = this.getCheckedNodeIndex(data[tab.defaultProps.id], data.treesrc_);
						/*索引可能是0
						 *这里应进行强类型判断
						 */
						if(index_ !== false) {
							this.remove(data[tab.defaultProps.id], index_, data.treesrc_, false);
						}
					}
				},
				/**
				 * 通过tab id获取该tab所在索引
				 * tabName：String 设置里面传入的tab id
				 * return i
				 * TODO：待优化
				 */
				getTabSettingByName: function(tabName) {
					for(var i = 0; i < this.tabs.length; i++) {
						if(tabName === this.tabs[i].id) {
							return i;
						}
					}
					return false;
				},
				/**
				 * 单击行的时候也能触发选中——内部方法
				 * 用户体验优化
				 */
				_handleCurrentChange: function(data, Node) {
					var index_ = this.getTabSettingByName(data.treesrc_),
						tab = this.tabs[index_];
					if(tab.singleSelet) {
						tab.allCheckeds = [];
						tab.allNodesId = [];
						this.add(data, tab);
					} else {
						Node.checked = !Node.checked;
					}
				},
				/**
				 * 标记数据来源——内部方法
				 */
				_setAllNodesId: function(treeArray, tabName, defaultProps) {
					for(var i = 0; i < treeArray.length; i++) {
						treeArray[i]["treesrc_"] = tabName;
						treeArray[i]["$checked"] = false;
						if(treeArray[i][defaultProps.children]) {
							this._setAllNodesId(treeArray[i][defaultProps.children], tabName, defaultProps);
						}
					}
					return treeArray;
				},
				getAllNodesId: function(treeArray, resultArray, defaultProps) {
					for(var i = 0; i < treeArray.length; i++) {
						resultArray.push(treeArray[i][defaultProps.id]);
						if(treeArray[i][defaultProps.children]) {
							this.getAllNodesId(treeArray[i][defaultProps.children], resultArray, defaultProps);
						}
					}
					return resultArray;
				},
				add: function(data, tabSetting) {
					var index_ = this.getTabSettingByName(data.treesrc_),
						tab = this.tabs[index_];
					if(tab.allNodesId.indexOf(data[tab.defaultProps.id]) > -1) {
						return;
					}
					if(tab.isPersonSeleted) {
						data.$checked = true;
						tab.allCheckeds.push(data);
					} else {
						tab.allCheckeds.push({
							avater: data.photoUrl,
							name: data[tab.defaultProps.label],
							id: data[tab.defaultProps.id]
						});
					}
					tab.allNodesId.push(data[tab.defaultProps.id]);
				},
				/**
				 * 获取指定tab下节点id在所有选中节点数组索引
				 * id：节点id
				 * treeSrc： String 设置里面传入的tab id
				 */
				getCheckedNodeIndex: function(id, treeSrc) {
					var index_ = this.getTabSettingByName(treeSrc);
					for(var i = 0; i < this.tabs[index_].allNodesId.length; i++) {
						if(this.tabs[index_].allNodesId[i] === id) {
							return i;
						}
					}
					return false;
				},
				/**
				 * 取消勾选指定tab下的tree节点
				 * id：节点id
				 * treeSrc： String 设置里面传入的tab id
				 */
				unchecked: function(id, treeSrc) {
					var index_ = this.getTabSettingByName(treeSrc),
						tab = this.tabs[index_],
						ref_ = this.$refs[tab.id][0];
					if(ref_.setChecked) {
						ref_.setChecked(id, false);
					} else {
						var row = this.getRowById(id, tab.data);
						row.$checked = false;
						ref_.toggleRowSelection(row, false);
					}
				},
				remove: function(id, index, treeSrc, byTag) {
					var index_ = this.getTabSettingByName(treeSrc);
					this.tabs[index_].allCheckeds.splice(index, 1);
					this.tabs[index_].allNodesId.splice(index, 1);
					/*通过标签直接取消勾选
					 *则直接unchecked而不是通过tree提供的回掉处理
					 */
					if(byTag) {
						this.unchecked(id, treeSrc);
					}
				},
				/**
				 * 确定按钮回调
				 * 如果回调函数返回false，则不关闭筛选器
				 */
				submit: function() {
					if(setting.ok) {
						if(isFunction(setting.ok)) {
							if(setting.ok.call(this) !== false) {
								this.hide();
							}
						} else {
							throw new Error("setting.ok应该提供一个回调函数");
						}
					}
				},
				/**
				 * tab切换时显示隐藏对应的tab内容——内部方法
				 */
				_changeTab: function(tabInstance) {
					var seleted_containers = this.$el.getElementsByClassName("seleted_container");
					var index_ = parseInt(tabInstance.index);
					for(var i = 0; i < this.tabs.length; i++) {
						this.tabs[i].display.display = "none";
						seleted_containers[i].style.display = "none";
					}
					this.tabs[index_].display.display = "block";
					seleted_containers[index_].style.display = "block";
				},
				/**
				 * 显示筛选器
				 */
				show: function() {
					this.visible = true;
				},
				/**
				 * 关闭筛选器
				 */
				hide: function() {
					this.visible = false;
				},
				/**
				 * 销毁筛选器实例
				 * 注意：destroy后需要手工设置变量为null
				 * test = VanyFilter();
				 * test.destroy();
				 * test = null;
				 */
				destroy: function() {
					this.hide();
					this.$el.parentNode.removeChild(this.$el)
				},
				// TODO：搜索
				filterNode: function(value, data) {
					if(!value) return true;
					return data.label.indexOf(value) !== -1;
				},
				/**
				 * 重置筛选条件
				 * index: Number 重置哪个tab的筛选条件
				 */
				resetFilter: function(index) {
					var options = this.tabs[index].form.options;
					for(var i = 0; i < options.length; i++) {
						if(options[i].type === "input") {
							options[i].model = "";
						} else {
							if(options[i].multiple) {
								options[i].model = [];
							} else {
								options[i].model = "";
							}
						}
					}
				},
				resetPaginationParams: function(index) {
					var tab = this.tabs[index];
					if(tab.pagination) {
						tab.data = [];
						tab.nodataFlag = false;
						tab.params.pageIndex = 1;
						tab.writeBackIds = tab.allNodesId.join(",");
					}
					return this;
				},
				paginationLoading: function(tabObj, e) {
					this._throttle(this._isScrollToBottom, e, this.getData, tabObj);
				},
				/**
				 * 判断一个可滚动元素是否滚动到了底部
				 */
				_isScrollToBottom: function(e, fn, context) {
					// e.srcElement存在兼容性问题，并非标准特性
					// https://developer.mozilla.org/zh-CN/docs/Web/API/Event/target
					// 支持 IE6-8
					var target_ = e.target || e.srcElement,
						// 距离顶部高度
						scrollTop = target_.scrollTop,
						// 滚动区域高度
						scrollHeight = target_.scrollHeight,
						// 文档元素高度
						clientHeight = target_.clientHeight;
					// 文档坐标和视口坐标转换，判断元素滚动到了底部
					if(scrollTop + clientHeight == scrollHeight) {
						if(fn) {
							fn.call(this, context);
						}
					}
				},
				/**
				 * 函数节流器
				 */
				_throttle: function(method, context) {
					clearTimeout(method.tId);
					var _arguments_ = arguments;
					method.tId = setTimeout(function() {
						var args = [];
						for(var i = 1; i < _arguments_.length; i++) {
							args.push(_arguments_[i]);
						}
						method.apply(this, args);
					}, 100);
				},
				getFilterValue: function(index) {
					this.resetPaginationParams(index);
					var params = this.tabs[index].params;
					var options = this.tabs[index].form.options;
					for(var i = 0; i < options.length; i++) {
						var key_ = options[i].formname;
						if(options[i].type === "input") {
							params[key_] = options[i].model;
						} else {
							if(options[i].multiple) {
								params[key_] = options[i].model.join(",")
							} else {
								params[key_] = options[i].model;
							}
						}
						if(params[key_].length === 0 || !params[key_]) {
							delete params[key_];
						}
					}
					this.getData(this.tabs[index]);
				},
				renderContent: function(h, node, data, store) {
					var self = this;
					return h("span", null, [h('span', null, node.label), h("span", {
						style: {
							float: "right"
						},
						domProps: {
							innerHTML: "(" + node.key + "    " + data.genderStr + ")",
						}
					}, "")]);
				},
				getSelectedValue: function(index){
					try{
						return this.tabs[index].allNodesId.join(",");
					}catch(e){
						return "";
					}
				},
				clear: function(index){
					var i,
						length;
					if(index){
						i = index;
						length = index + 1;
					}else{
						i = 0;
						length = this.tabs.length;
					}
					for(; i<length; i++){
						this.tabs[i].allCheckeds = [];
						this.tabs[i].allNodesId = [];
						try{
							this.resetFilter(i);
						}catch(e){}
						if(this.tabs[i].isPersonSeleted){
							this.$refs[this.tabs[i].id][0].clearSelection();
						}
					}
				}
			}
		});
		return vanyfilter;
	}

	/**
	 * setting说明
	 * mountEl：String 挂在元素id #id
	 * title：String 筛选器标题
	 * tabs：Array 筛选器tab设置
	 * {
	 * 	"name": tab名称
	 * 	"id": tab id
	 * 	"singleSelet"：Boolean 是否只支持单选默认多选
	 * 	"url"：String 树数据请求地址
	 * 	"writeBackIds"：String 需要回写的数据 逗号隔开的字符串
	 * 	"defaultProps"：Object 树数据结构键名
	 * 		{
	 * 			"children": 'children',
				"label": 'tagName',
				"id": "tagCode"
	 * 		}
	 * }
	 * ok：Function 确定按钮回调
	 */
	window.VanyFilter = function(setting) {
		return new VanyFilter_(setting);
	}
})();